package com.witmore.ftp.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.witmore.ftp.db.entity.FtpConnectionDO;
import com.witmore.ftp.db.entity.FtpFileLogDO;
import com.witmore.ftp.db.entity.FtpUserDO;
import com.witmore.ftp.db.mapper.FtpConnectionMapper;
import com.witmore.ftp.db.mapper.FtpFileLogMapper;
import com.witmore.ftp.db.mapper.FtpUserMapper;
import com.witmore.ftp.web.config.FtpProperties;
import com.witmore.ftp.web.vo.FileLogQueryVO;
import com.witmore.ftp.web.vo.ConnectionQueryVO;
import com.jk.common.response.ResponseResult;
import com.jk.common.response.ResponsePageResult;
import com.jk.common.response.PageParamVO;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.http.MediaType;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;

/**
 * FTP监控控制器
 */
@RestController
@RequestMapping("/api/ftp")
@RequiredArgsConstructor
public class FtpMonitorController {

    private final FtpUserMapper ftpUserMapper;
    private final FtpFileLogMapper ftpFileLogMapper;
    private final FtpConnectionMapper ftpConnectionMapper;
    private final FtpProperties ftpProperties;

    /**
     * 获取FTP服务器状态
     */
    @GetMapping("/status")
    public ResponseResult<Map<String, Object>> getServerStatus() {
        Map<String, Object> status = new HashMap<>();

        // 服务器配置信息
        status.put("port", ftpProperties.getServer().getPort());
        status.put("maxConnections", ftpProperties.getServer().getMaxConnections());
        status.put("rootDirectory", ftpProperties.getServer().getRootDirectory());
        status.put("passivePorts", ftpProperties.getServer().getPassivePorts());

        // 统计信息
        long totalUsers = ftpUserMapper.selectCount(new LambdaQueryWrapper<FtpUserDO>().eq(FtpUserDO::getIsDeleted, 0));
        long totalConnections = ftpConnectionMapper.selectCount(new LambdaQueryWrapper<FtpConnectionDO>().eq(FtpConnectionDO::getIsDeleted, 0));
        long totalFileLogs = ftpFileLogMapper.selectCount(new LambdaQueryWrapper<FtpFileLogDO>().eq(FtpFileLogDO::getIsDeleted, 0));

        status.put("totalUsers", totalUsers);
        status.put("totalConnections", totalConnections);
        status.put("totalFileLogs", totalFileLogs);

        return ResponseResult.success(status);
    }

    /**
     * 获取用户列表（简单版本，用于监控）
     */
    @GetMapping("/users/simple")
    public ResponseResult<List<FtpUserDO>> getUsersSimple() {
        LambdaQueryWrapper<FtpUserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FtpUserDO::getIsDeleted, 0)
                   .select(FtpUserDO::getId, FtpUserDO::getUsername, FtpUserDO::getEnabled);
        List<FtpUserDO> users = ftpUserMapper.selectList(queryWrapper);
        return ResponseResult.success(users);
    }

    /**
     * 获取文件操作日志
     */
    @GetMapping("/file-logs")
    public ResponsePageResult<FtpFileLogDO> getFileLogs(FileLogQueryVO queryVO) {
        
        // 设置默认分页参数
        if (queryVO.getPage() == null || queryVO.getPage() <= 0) {
            queryVO.setPage(1);
        }
        if (queryVO.getSize() == null || queryVO.getSize() <= 0) {
            queryVO.setSize(20);
        }
        
        Page<FtpFileLogDO> pageObj = new Page<>(queryVO.getPage(), queryVO.getSize());
        
        LambdaQueryWrapper<FtpFileLogDO> queryWrapper = new LambdaQueryWrapper<FtpFileLogDO>()
                .eq(queryVO.getUsername() != null && !queryVO.getUsername().trim().isEmpty(), 
                    FtpFileLogDO::getUsername, queryVO.getUsername() != null ? queryVO.getUsername().trim() : null)
                .eq(queryVO.getOperationType() != null && !queryVO.getOperationType().trim().isEmpty(), 
                    FtpFileLogDO::getOperationType, queryVO.getOperationType() != null ? queryVO.getOperationType().trim() : null)
                .eq(queryVO.getStatus() != null && !queryVO.getStatus().trim().isEmpty(), 
                    FtpFileLogDO::getStatus, queryVO.getStatus() != null ? queryVO.getStatus().trim() : null)
                .like(queryVO.getFileName() != null && !queryVO.getFileName().trim().isEmpty(), 
                      FtpFileLogDO::getFileName, queryVO.getFileName() != null ? queryVO.getFileName().trim() : null)
                .like(queryVO.getFilePath() != null && !queryVO.getFilePath().trim().isEmpty(), 
                      FtpFileLogDO::getFilePath, queryVO.getFilePath() != null ? queryVO.getFilePath().trim() : null)
                .eq(queryVO.getClientIp() != null && !queryVO.getClientIp().trim().isEmpty(), 
                    FtpFileLogDO::getClientIp, queryVO.getClientIp() != null ? queryVO.getClientIp().trim() : null)
                .ge(queryVO.getStartTime() != null && !queryVO.getStartTime().trim().isEmpty(), 
                    FtpFileLogDO::getCreateTime, queryVO.getStartTime() != null ? queryVO.getStartTime().trim() : null)
                .le(queryVO.getEndTime() != null && !queryVO.getEndTime().trim().isEmpty(), 
                    FtpFileLogDO::getCreateTime, queryVO.getEndTime() != null ? queryVO.getEndTime().trim() : null)
                .eq(FtpFileLogDO::getIsDeleted, 0);
        
        // 处理排序
        if (queryVO.getSortField() != null && !queryVO.getSortField().isEmpty()) {
            if ("DESC".equalsIgnoreCase(queryVO.getSortOrder())) {
                queryWrapper.orderByDesc(getFieldFunction(queryVO.getSortField()));
            } else {
                queryWrapper.orderByAsc(getFieldFunction(queryVO.getSortField()));
            }
        } else {
            queryWrapper.orderByDesc(FtpFileLogDO::getCreateTime);
        }
        
        Page<FtpFileLogDO> result = ftpFileLogMapper.selectPage(pageObj, queryWrapper);
        return ResponsePageResult.success(result);
    }

    /**
     * 获取连接记录
     */
    @GetMapping("/connections")
    public ResponsePageResult<FtpConnectionDO> getConnections(ConnectionQueryVO queryVO) {

        // 设置默认分页参数
        if (queryVO.getPage() == null || queryVO.getPage() <= 0) {
            queryVO.setPage(1);
        }
        if (queryVO.getSize() == null || queryVO.getSize() <= 0) {
            queryVO.setSize(20);
        }

        Page<FtpConnectionDO> pageObj = new Page<>(queryVO.getPage(), queryVO.getSize());
        LambdaQueryWrapper<FtpConnectionDO> queryWrapper = new LambdaQueryWrapper<FtpConnectionDO>()
                .eq(queryVO.getUsername() != null && !queryVO.getUsername().trim().isEmpty(), 
                    FtpConnectionDO::getUsername, queryVO.getUsername() != null ? queryVO.getUsername().trim() : null)
                .eq(queryVO.getClientIp() != null && !queryVO.getClientIp().trim().isEmpty(), 
                    FtpConnectionDO::getClientIp, queryVO.getClientIp() != null ? queryVO.getClientIp().trim() : null)
                .eq(queryVO.getStatus() != null && !queryVO.getStatus().trim().isEmpty(), 
                    FtpConnectionDO::getStatus, queryVO.getStatus() != null ? queryVO.getStatus().trim() : null)
                .ge(queryVO.getStartTime() != null && !queryVO.getStartTime().trim().isEmpty(), 
                    FtpConnectionDO::getConnectTime, queryVO.getStartTime() != null ? queryVO.getStartTime().trim() : null)
                .le(queryVO.getEndTime() != null && !queryVO.getEndTime().trim().isEmpty(), 
                    FtpConnectionDO::getConnectTime, queryVO.getEndTime() != null ? queryVO.getEndTime().trim() : null)
                .eq(FtpConnectionDO::getIsDeleted, 0);

        // 处理排序
        if (queryVO.getSortField() != null && !queryVO.getSortField().isEmpty()) {
            if ("DESC".equalsIgnoreCase(queryVO.getSortOrder())) {
                queryWrapper.orderByDesc(getConnectionFieldFunction(queryVO.getSortField()));
            } else {
                queryWrapper.orderByAsc(getConnectionFieldFunction(queryVO.getSortField()));
            }
        } else {
            queryWrapper.orderByDesc(FtpConnectionDO::getConnectTime);
        }

        Page<FtpConnectionDO> result = ftpConnectionMapper.selectPage(pageObj, queryWrapper);
        return ResponsePageResult.success(result);
    }

    /**
     * 获取最近的文件操作统计
     */
    @GetMapping("/stats/recent")
    public ResponseResult<Map<String, Object>> getRecentStats() {
        Map<String, Object> stats = new HashMap<>();

        // 最近24小时的上传下载统计
        LambdaQueryWrapper<FtpFileLogDO> baseQuery = new LambdaQueryWrapper<>();
        baseQuery.ge(FtpFileLogDO::getCreateTime, "DATE_SUB(NOW(), INTERVAL 24 HOUR)")
                 .eq(FtpFileLogDO::getIsDeleted, 0);

        // 上传统计
        LambdaQueryWrapper<FtpFileLogDO> uploadQuery = baseQuery.clone();
        uploadQuery.eq(FtpFileLogDO::getOperationType, "UPLOAD");
        long uploadCount = ftpFileLogMapper.selectCount(uploadQuery);

        // 下载统计
        LambdaQueryWrapper<FtpFileLogDO> downloadQuery = baseQuery.clone();
        downloadQuery.eq(FtpFileLogDO::getOperationType, "DOWNLOAD");
        long downloadCount = ftpFileLogMapper.selectCount(downloadQuery);

        stats.put("uploadCount24h", uploadCount);
        stats.put("downloadCount24h", downloadCount);

        return ResponseResult.success(stats);
    }

    /**
     * 健康检查
     */
    @GetMapping("/health")
    public ResponseResult<Map<String, String>> health() {
        Map<String, String> health = new HashMap<>();
        health.put("status", "UP");
        health.put("service", "Witmore FTP Server");
        return ResponseResult.success(health);
    }

    /**
     * 图片文件预览
     */
    @GetMapping("/file-preview")
    public ResponseEntity<Resource> previewFile(
            @RequestParam String username,
            @RequestParam String filePath) {

        try {
            // 构建完整的文件路径
            String rootDirectory = ftpProperties.getServer().getRootDirectory();
            Path fullPath = Paths.get(rootDirectory, "users", username, filePath);
            File file = fullPath.toFile();

            // 检查文件是否存在
            if (!file.exists() || !file.isFile()) {
                return ResponseEntity.notFound().build();
            }

            // 检查文件是否在允许的目录范围内（安全检查）
            Path userDirectory = Paths.get(rootDirectory, "users", username);
            if (!fullPath.normalize().startsWith(userDirectory.normalize())) {
                return ResponseEntity.badRequest().build();
            }

            // 检查是否为图片文件
            String fileName = file.getName().toLowerCase();
            if (!isImageFile(fileName)) {
                return ResponseEntity.badRequest().build();
            }

            // 创建资源
            Resource resource = new FileSystemResource(file);

            // 确定媒体类型
            String contentType = Files.probeContentType(fullPath);
            if (contentType == null) {
                contentType = getContentTypeByExtension(fileName);
            }

            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + file.getName() + "\"")
                    .body(resource);

        } catch (Exception e) {
            return ResponseEntity.internalServerError().build();
        }
    }

    /**
     * 检查是否为图片文件
     */
    private boolean isImageFile(String fileName) {
        String[] imageExtensions = {".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".svg", ".ico"};
        for (String ext : imageExtensions) {
            if (fileName.endsWith(ext)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 根据文件扩展名获取内容类型
     */
    private String getContentTypeByExtension(String fileName) {
        if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (fileName.endsWith(".png")) {
            return "image/png";
        } else if (fileName.endsWith(".gif")) {
            return "image/gif";
        } else if (fileName.endsWith(".bmp")) {
            return "image/bmp";
        } else if (fileName.endsWith(".webp")) {
            return "image/webp";
        } else if (fileName.endsWith(".svg")) {
            return "image/svg+xml";
        } else if (fileName.endsWith(".ico")) {
            return "image/x-icon";
        }
        return "application/octet-stream";
    }

    /**
     * 获取文件日志排序字段映射
     */
    private SFunction<FtpFileLogDO, ?> getFieldFunction(String sortField) {
        return switch (sortField.toLowerCase()) {
            case "createtime", "create_time" -> FtpFileLogDO::getCreateTime;
            case "username" -> FtpFileLogDO::getUsername;
            case "operationtype", "operation_type" -> FtpFileLogDO::getOperationType;
            case "filesize", "file_size" -> FtpFileLogDO::getFileSize;
            case "status" -> FtpFileLogDO::getStatus;
            default -> FtpFileLogDO::getCreateTime;
        };
    }

    /**
     * 获取连接记录排序字段映射
     */
    private SFunction<FtpConnectionDO, ?> getConnectionFieldFunction(String sortField) {
        return switch (sortField.toLowerCase()) {
            case "connecttime", "connect_time" -> FtpConnectionDO::getConnectTime;
            case "disconnecttime", "disconnect_time" -> FtpConnectionDO::getDisconnectTime;
            case "username" -> FtpConnectionDO::getUsername;
            case "clientip", "client_ip" -> FtpConnectionDO::getClientIp;
            case "duration" -> FtpConnectionDO::getDuration;
            case "status" -> FtpConnectionDO::getStatus;
            default -> FtpConnectionDO::getConnectTime;
        };
    }
}
